package com.xm.controller;

import com.xm.email.core.MailInfo;
import com.xm.email.test.TestEmail;
import com.xm.model.Msg;
import com.xm.service.RabbitService;
import com.xm.util.FileUtil;
import com.xm.util.old.JacksonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@RestController
@Slf4j
public class SendMessageController {
    @Autowired
    private RabbitService rabbitService;

    /**
     *  http://localhost:8081/sendDirectMessage
     */
    @GetMapping("/sendDirectMessage")
    public String sendDirectMessage(){
        String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Msg msg = Msg.builder().msgId(String.valueOf(UUID.randomUUID()))
                .content("one message from direct exchange by sendDirectMessage")
                .createTime(createTime)
                .build();
        rabbitService.sendDirectMsg(msg);
        return "ok";
    }

    /**
     *  http://localhost:8081/sendDirectMessage2
     */
    @GetMapping("/sendDirectMessage2")
    public String sendDirectMessage2(){
        String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        String str = "one message from direct exchange by sendDirectMessage2";
        rabbitService.sendDirectMsg(str);
        return "ok";
    }

    /**
     *  http://localhost:8081/sendTopicMessage
     */
    @GetMapping("/sendTopicMessage")
    public String sendTopicMessage(){
        String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Msg msg = Msg.builder().msgId(String.valueOf(UUID.randomUUID()))
                .content("one message from topic exchange by sendTopicMessage")
                .createTime(createTime)
                .build();
        rabbitService.sendMsg("topicExchange", "topic.A", msg);
        rabbitService.sendMsg("topicExchange", "topic.B", msg);
        return "ok";
    }

    /**
     *  http://localhost:8081/sendTopicMessage2
     */
    @GetMapping("/sendTopicMessage2")
    public String sendTopicMessage2(){
        String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Msg msg = Msg.builder().msgId(String.valueOf(UUID.randomUUID()))
                .content("one message from topic exchange by sendTopicMessage2")
                .createTime(createTime)
                .build();
        rabbitService.sendMsg("topicExchange", "topic.C", msg);
        return "ok";
    }

    /**
     *  http://localhost:8081/sendFanoutMessage
     */
    @GetMapping("/sendFanoutMessage")
    public String sendFanoutMessage(){
        String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Msg msg = Msg.builder().msgId(String.valueOf(UUID.randomUUID()))
                .content("one message from fanout exchange by sendFanoutMessage")
                .createTime(createTime)
                .build();
        rabbitService.sendMsg("fanoutExchange", null, msg);
        return "ok";
    }

    /**
     *  http://localhost:8081/sendAckMessage/0
     */
    @GetMapping("/sendAckMessage/{number}")
    public String sendAckMessage(@PathVariable("number") Integer number){
        String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Msg msg = Msg.builder().msgId(String.valueOf(UUID.randomUUID()))
                .content("one message from some exchange/routingKey by sendAckMessage")
                .createTime(createTime)
                .build();
        if(0 == number || 2 == number){
            log.info("推送消息，有路由键无交换机");
            rabbitService.sendMsg("non-existent-exchange", "directRoutingKey", msg);
        }else if(1 == number){
            log.info("推送消息，有路由键有交换机无队列");
            rabbitService.sendMsg("noneQueueDirectExchange", "directRoutingKey", msg);
        }else if(3 == number){
            log.info("推送消息，无路由键无交换机");
            rabbitService.sendMsg("non-existent-exchange", "non-existent-routingKey", msg);
        }else{
            log.info("推送消息，有路由键有交换机有队列");
            rabbitService.sendDirectMsg(msg);
        }
        return "ok";
    }

    /**
     * 以上接口调用时，application.yml文件需打开设置publisher-confirm-type、publisher-returns
     * 以上接口调用时，application.yml文件需打开设置publisher-confirm-type、publisher-returns
     * 以上接口调用时，application.yml文件需打开设置publisher-confirm-type、publisher-returns
     * 并关闭确认机制manual，否则消息不回被监听器消费确认
     */

    /**
     *  Message 直接发送实体类对象，监听器接手并消费消息后，在basicPublic重新发布消息时会出现Message cannot convert to msg相关异常！！舍弃
     *  http://localhost:8081/sendAckMessage
     */
    @GetMapping("/sendAckMessage")
    public String sendAckMessage(){
        Msg msg = null;
        for (int i = 0; i < 10; i++) {
            msg = Msg.builder().msgId(String.valueOf(UUID.randomUUID()))
                    .content("one message from direct exchange by sendAckMessage")
                    .createTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")))
                    .build();
            rabbitService.sendAckMsg("directQueueAck", msg);
        }
        return "ok";
    }

    /**
     *  将实体类转json后发送后，支持basicPublic重新发布消息
     *  http://localhost:8081/sendAckMessage2
     */
    @GetMapping("/sendAckMessage2")
    public String sendAckMessage2(){
        for (int i = 0; i < 10; i++) {
            Msg msg = Msg.builder().msgId(String.valueOf(UUID.randomUUID()))
                    .content("one message from direct exchange by sendAckMessage2")
                    .createTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")))
                    .build();
            String msgStr = JacksonUtil.obj2String(msg);
            rabbitService.sendMsg("directExchangeAck", "directRoutingKeyAck", msgStr);
        }
        return "ok";
    }

    /**
     *  将实体类转json后发送后，支持basicPublic重新发布消息
     *  http://localhost:8081/sendEmailAckMessage
     */
    @GetMapping("/sendEmailAckMessage")
    public String sendEmailAckMessage() throws UnsupportedEncodingException {
        String[] body = {"土坡上的狗尾巴草", "在你的身边", "白鸽乌鸦相爱的戏码", "安河桥", "罗生门", "下坠falling"};
        MailInfo mailInfo = TestEmail.getTextSample();
        log.info("开始推送邮件消息。。text={}", mailInfo);

        mailInfo.setContent(Arrays.toString(body));
        String content = JacksonUtil.obj2String(mailInfo);

        Msg msg = Msg.builder().msgId(String.valueOf(UUID.randomUUID()))
                .content(content)
                .createTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")))
                .type(1)
                .build();
        String msgStr = JacksonUtil.obj2String(msg);
        rabbitService.sendMsg("directEmailExchangeAck", "directEmailRoutingKeyAck", msgStr);

        mailInfo = TestEmail.getHtmlSample();
        log.info("开始推送邮件消息。。html={}", mailInfo);
        mailInfo.setContent("<div style=\"background-color: lightblue; width: auto; height:auto;\">这是一个有背景色和尺寸的div元素。</div>");

        List<String> fileList = new ArrayList<>();
//        fileList.add("D:\\三国.pdf");//27M的文件上传了72s
        //添加绝对路径文件
//        fileList.add("D:\\二哈.png");
        //添加项目中文件
        fileList.add(FileUtil.getResourcePathUtf8("static/test/二哈.png"));
        mailInfo.setFileList(fileList);
        List<File> files = new ArrayList<>();
        files.add(new File(Objects.requireNonNull(FileUtil.getResourcePathUtf8("static/images/善逸.jpg"))));
        mailInfo.setFiles(files);

        msg = Msg.builder().msgId(String.valueOf(UUID.randomUUID()))
                .content(JacksonUtil.obj2String(mailInfo))
                .createTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")))
                .type(1)
                .build();
        msgStr = JacksonUtil.obj2String(msg);
        rabbitService.sendMsg("directEmailExchangeAck", "directEmailRoutingKeyAck", msgStr);
        return "ok";
    }


    /**
     * http://localhost:8081/sendAckMessage11/3
     *  生产者以字符串格式发送消息，消费者basicPublish时就允许以相同格式进行转发
     *  （对比AckReceiver.process2方法中msg.type为3时的转发，直接转发msgStr.getByte()转发的是Map对象；而直接转发amqpMsg.getBody()转发的是Json字符串）
     * @param number 0-ack；1-reject；2-nack；3-publish；其他-throw new RuntimeException("消息类型错误");
     * @return
     */
    @GetMapping("/sendAckMessage11/{number}")
    public String sendAckMessage11(@PathVariable("number") Integer number){
        Msg msg = Msg.builder().msgId(String.valueOf(UUID.randomUUID()))
                .content("hello rabbitmq callback")
                .createTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")))
                .type(number)
                .build();
        rabbitService.sendAckCallbackMsg("directQueueAck11", JacksonUtil.obj2String(msg));
        return "ok";
    }

}
